package dish

import (
	"context"
	"github.com/google/uuid"
	"github.com/shopspring/decimal"
	"github.com/zeromicro/go-zero/core/logx"
	"insighttracking/apps/admin/auth"
	"insighttracking/apps/admin/internal/svc"
	"insighttracking/apps/admin/internal/types"
	types2 "insighttracking/common/types"
	"insighttracking/common/utils"
	"insighttracking/query/bo"
	"insighttracking/query/model"
	"insighttracking/query/service"
	"net/http"
	"os"
)

type ApiLogic struct {
	logx.Logger
	ctx     context.Context
	svcCtx  *svc.ServiceContext
	Request *http.Request
}

func NewApiLogic(ctx context.Context, svcCtx *svc.ServiceContext, request *http.Request) *ApiLogic {
	hostname, _ := os.Hostname()
	return &ApiLogic{
		Logger: logx.WithContext(ctx).WithCallerSkip(0).WithFields(
			logx.Field("Log_UUID", uuid.New().String()),
			logx.Field("hostname", hostname)),
		ctx:     ctx,
		svcCtx:  svcCtx,
		Request: request,
	}
}

func (l *ApiLogic) CreateApi(req *types.CreateDishReq) (resp string, err error) {
	accountInfo, err := auth.GetAccountInfo(l.svcCtx, l.Request)
	if err != nil {
		return
	}

	spuIds := make([]int64, 0)
	var salesPrice decimal.Decimal
	for _, item := range req.SpuRatio {
		spuIds = append(spuIds, item.SpuID)
	}
	spuEntities, err := service.SpuService.GetSpuByIdListApi(l.ctx, spuIds)
	if err != nil {
		return
	}
	for _, item := range spuEntities {
		salesPrice = salesPrice.Add(item.LossRate.Div(decimal.New(100, 0)).Add(decimal.New(1, 0)).Mul(item.SalesPrice))
	}

	dishesEntity := model.DishesEntity{
		EnterpriseID: accountInfo.EnterpriseId,
		Name:         req.Name,
		Code:         req.Code,
		Image:        req.Image,
		Describe:     req.Describe,
		IsEnable:     req.IsEnable,
		SalesPrice:   salesPrice,
	}
	err = service.DishService.CreateApi(l.ctx, &dishesEntity)
	if err != nil {
		return "", err
	}

	dishesSpuRatioEntities := make([]*model.DishesSpuRatioEntity, 0)
	for _, item := range req.SpuRatio {
		dishesSpuRatioEntities = append(dishesSpuRatioEntities, &model.DishesSpuRatioEntity{
			DishesID: dishesEntity.ID,
			SpuID:    item.SpuID,
			Percent:  item.Percent,
		})
	}
	err = service.DishService.BatchCreateDishSpuRatioApi(l.ctx, dishesSpuRatioEntities)
	if err != nil {
		return
	}
	return
}

func (l *ApiLogic) GetPagesApi(req *types.DishPagesReq) (resp types.DishPagesResp, err error) {
	resp = types.DishPagesResp{}
	data := make([]types.DishPagesData, 0)
	accountInfo, err := auth.GetAccountInfo(l.svcCtx, l.Request)
	if err != nil {
		return
	}
	dishPagesBo := bo.DishPagesReq{
		Name:         req.Name,
		Code:         req.Code,
		IsEnable:     req.IsEnable,
		EnterpriseID: accountInfo.EnterpriseId,
		PageNumber:   req.PageNumber,
		PageSize:     req.PageSize,
	}
	entities, count, err := service.DishService.GetPagesApi(l.ctx, &dishPagesBo)
	if err != nil {
		return
	}
	for _, entity := range entities {
		data = append(data, types.DishPagesData{
			ID:        entity.ID,
			Name:      entity.Name,
			Code:      entity.Code,
			IsEnable:  entity.IsEnable,
			Describe:  entity.Describe,
			CreatedAt: utils.TimestampToString(entity.CreatedAt),
			UpdatedAt: utils.TimestampToString(entity.UpdatedAt),
		})
	}
	resp.PageNumber = req.PageNumber
	resp.PageSize = req.PageSize
	resp.Total = count
	resp.Data = data
	return
}

func (l *ApiLogic) NameAssociateApi(req *types.AssociateReq) (resp types.DishAssociateResp, err error) {
	entities, err := service.DishService.GetListByNameApi(l.ctx, req.Name)
	if err != nil {
		return
	}
	data := make([]*types2.SimpleList, 0)
	for _, entity := range entities {
		data = append(data, &types2.SimpleList{
			ID:   entity.ID,
			Name: entity.Name,
			Code: entity.Code,
		})
	}
	resp = types.DishAssociateResp{
		Data: data,
	}
	return
}

func (l *ApiLogic) ModifyEnableApi(req *types.IdReq, status int64) (resp string, err error) {
	err = service.DishService.ModifyByIDApi(l.ctx, req.Id, status)
	return
}

func (l *ApiLogic) GetDetailApi(req *types.IdReq) (resp *types.DishDetailResp, err error) {
	resp = &types.DishDetailResp{}
	data := make([]*types.SpuRatioInfo, 0)

	entity, err := service.DishService.GetByIDApi(l.ctx, req.Id)
	if err != nil {
		return
	}
	spuRatioInfo, err := service.DishService.GetSpuRatioApi(l.ctx, req.Id)
	for _, item := range spuRatioInfo {
		data = append(data, &types.SpuRatioInfo{
			SpuID:           item.SpuID,
			Name:            item.Name,
			Percent:         item.Percent,
			ProductImageUrl: item.ProductImageUrl,
			SpuType:         item.SpuType,
			UnitName:        item.UnitName,
		})
	}
	resp.SpuRatioInfo = data
	resp.Name = entity.Name
	resp.Code = entity.Code
	resp.Describe = entity.Describe
	resp.Image = entity.Image
	return
}

func (l *ApiLogic) EditApi(req *types.EditDishReq) (resp string, err error) {
	accountInfo, err := auth.GetAccountInfo(l.svcCtx, l.Request)
	if err != nil {
		return
	}

	spuIds := make([]int64, 0)
	var salesPrice decimal.Decimal
	for _, item := range req.SpuRatio {
		spuIds = append(spuIds, item.SpuID)
	}
	spuEntities, err := service.SpuService.GetSpuByIdListApi(l.ctx, spuIds)
	if err != nil {
		return
	}
	for _, item := range spuEntities {
		salesPrice = salesPrice.Add(item.LossRate.Div(decimal.New(100, 0)).Add(decimal.New(1, 0)).Mul(item.SalesPrice))
	}

	dishesEntity := model.DishesEntity{
		ID:           req.ID,
		EnterpriseID: accountInfo.EnterpriseId,
		Name:         req.Name,
		Code:         req.Code,
		Image:        req.Image,
		Describe:     req.Describe,
		IsEnable:     req.IsEnable,
		SalesPrice:   salesPrice,
	}
	err = service.DishService.EditApi(l.ctx, &dishesEntity)
	if err != nil {
		return "", err
	}

	err = service.DishService.DeleteDishSpuRatioApi(l.ctx, req.ID)
	if err != nil {
		return
	}
	dishesSpuRatioEntities := make([]*model.DishesSpuRatioEntity, 0)
	for _, item := range req.SpuRatio {
		dishesSpuRatioEntities = append(dishesSpuRatioEntities, &model.DishesSpuRatioEntity{
			DishesID: dishesEntity.ID,
			SpuID:    item.SpuID,
			Percent:  item.Percent,
		})
	}
	err = service.DishService.BatchCreateDishSpuRatioApi(l.ctx, dishesSpuRatioEntities)
	if err != nil {
		return
	}
	return
}
